﻿using CleanArchitecture.Core;
using CleanArchitecture.Core.Handlers;
using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Infrastructure.Interfaces;
using CleanArchitecture.Infrastructure.Interfaces.Security;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;

namespace CleanArchitecture.Web.Filters
{
    /// <summary>
    /// 对后台分配系统模块的按钮进行了角色授权后，验证按钮是否有操作权限
    /// </summary>
    public class AuthorizeButtonAttribute : ActionFilterAttribute
    {
        #region Ctor
        /// <summary>
        /// Create instance of the filter attribute
        /// </summary>
        public AuthorizeButtonAttribute() : base()
        {
        }

        #endregion

        #region Methods
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));
            try
            {
                if (!(context.ActionArguments.TryGetValue("buttonid", out object value)
                                && value is int buttonid))
                    throw new NowaException("Invalid Argument of buttonid");
                if (!(context.ActionArguments.TryGetValue("moduleid", out object value1)
                                && value1 is int moduleid))
                    throw new NowaException("Invalid Argument of moduleid");
                var workContext = EngineContext.Current.Resolve<IWorkContext>();
                var permissionService = EngineContext.Current.Resolve<IPermissionService>();
                if (workContext.IsAdmin) return; //超级管理员拥有所有操作权限
                if(!permissionService.AuthorizeModuleButton(moduleid, buttonid))
                {
                    var webHelper = EngineContext.Current.Resolve<IWebHelper>();
                    context.HttpContext.Response.StatusCode = 403;
                    context.Result = new RedirectToActionResult("AccessDenied", "Security", new { pageUrl = webHelper.GetRawUrl(context.HttpContext.Request) });
                }
                return;
            }
            catch(Exception ex)
            {
                context.HttpContext.Response.StatusCode = 400;
                context.Result = new ContentResult()
                {
                    Content = ex.Message
                };
                return;
            }
        }
        #endregion
    }
}
